package com.zksb.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zksb.entity.Goods;
import com.zksb.entity.Food;
import com.zksb.service.CartService;
import com.zksb.service.FoodService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@Service
public class CartServiceImpl implements CartService {

    private final String CARETS = "carts";

    @Autowired
    private FoodService foodService;

    @Override
    public int add(HttpServletRequest request, HttpServletResponse response, Integer goodsId, Integer quantity) {
        Food food = foodService.get(goodsId);//获取商品对象

        Map<Integer, Goods> carts = getCart(request);//获取购物车

        Goods goods;
        if (carts.containsKey(goodsId)) {
            goods = carts.get(goodsId);
            goods.setQuantity(goods.getQuantity() + quantity); //修改数量
        } else {
            goods = new Goods();
            BeanUtils.copyProperties(food, goods);//把food对象的值设置到cart对象。前提：两个对象的get set方法一致。
            goods.setQuantity(quantity);//设置数量
        }

        goods.setAmount(goods.getQuantity() * food.getPrice());//设置总金额
        carts.put(goodsId, goods);//把商品对象保存到购物车

        saveCart(request, response, carts);//保存购物车
        return carts.size();
    }

    @Override
    public Goods update(HttpServletRequest request, HttpServletResponse response, Integer goodsId, Integer quantity) {
        Map<Integer, Goods> carts = getCart(request);

        if (carts.containsKey(goodsId)) {
            Goods goods = carts.get(goodsId);
            goods.setQuantity(quantity); //修改数量
            goods.setAmount(goods.getQuantity() * goods.getPrice());//设置总金额
            carts.put(goodsId, goods);//把商品对象保存到购物车

            saveCart(request, response, carts);//保存购物车
        } else {
            add(request, response, goodsId, quantity);
            carts = getCart(request);
        }

        return carts.get(goodsId);
    }

    @Override
    public int delete(HttpServletRequest request, HttpServletResponse response, Integer goodsId) {
        Map<Integer, Goods> carts = getCart(request);
        if (carts.containsKey(goodsId)) {
            carts.remove(goodsId);
        }

        saveCart(request, response, carts);//保存购物车
        return carts.size();
    }

    private void saveCart(HttpServletRequest request, HttpServletResponse response, Map<Integer, Goods> carts) {
//        request.getSession().setAttribute("carts", carts);

        if (carts == null) {
            return;
        }

        try {
            ObjectMapper mapper = new ObjectMapper();
            String json = mapper.writeValueAsString(carts);
            json = java.net.URLEncoder.encode(json, "UTF-8");//编码

            Cookie cartCookie = new Cookie(CARETS, json);
            cartCookie.setMaxAge(-1);//设置过期时间，-1表示永不过期
            response.addCookie(cartCookie);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Map<Integer, Goods> getCart(HttpServletRequest request) {
        //Map<Integer, Goods> carts = (Map<Integer, Goods>) request.getSession().getAttribute("carts");

        Cookie[] cookies = request.getCookies();
        String cartValue = "";
        for (Cookie cookie : cookies) {
            if (CARETS.equals(cookie.getName())) {
                cartValue = cookie.getValue();
                break;
            }
        }

        Map<Integer, Goods> carts = null;
        try {
            if (cartValue != null && !"".equals(cartValue)) {
                cartValue = java.net.URLDecoder.decode(cartValue, "UTF-8");//解码
                ObjectMapper mapper = new ObjectMapper();
                carts = mapper.readValue(cartValue, new TypeReference<Map<Integer, Goods>>(){});
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return carts == null ? new LinkedHashMap<>() : carts;
    }
}
